package com.sky.service.admin.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.StatusConstant;
import com.sky.dto.SetmealDTO;
import com.sky.dto.SetmealPageQueryDTO;
import com.sky.exception.DeletionNotAllowedException;
import com.sky.exception.SetmealEnableFailedException;
import com.sky.mapper.admin.DishMapper;
import com.sky.mapper.admin.SetmealDishMapper;
import com.sky.mapper.admin.SetmealMapper;
import com.sky.pojo.Dish;
import com.sky.pojo.Setmeal;
import com.sky.pojo.SetmealDish;
import com.sky.result.PageResult;
import com.sky.service.admin.SetmealService;
import com.sky.vo.SetmealVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.List;

/**
 * @version: 1.0
 * @Author: 李佳毅
 * @description:
 * @date: 2025-07-08 9:30
 */
@Service
public class SetmealServiceImpl implements SetmealService {

    @Autowired
    private SetmealMapper setmealMapper;

    @Autowired
    private SetmealDishMapper setmealDishMapper;

    //注入dishMapper
    @Autowired
    private DishMapper dishMapper;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveWithDish(SetmealDTO setmealDTO) {
        /**
         * 1. 保存套餐数据
         * 2. 得到保存的套餐id
         * 3. 遍历List<SetmealDish>集合, 给每个SetmealDish设置套餐id
         * 4. 批量保存套餐和菜品的关联关系
         */
        Setmeal setmeal = new Setmeal();
        //复制属性
        BeanUtils.copyProperties(setmealDTO, setmeal);
        //保存套餐数据
        int row1 = setmealMapper.insert(setmeal);
        //得到保存的套餐id
        Long setmealId = setmeal.getId();
        //遍历List<SetmealDish>集合, 给每个SetmealDish设置套餐id
        List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();
        if (!CollectionUtils.isEmpty(setmealDishes)) {
            setmealDishes.forEach(setmealDish -> setmealDish.setSetmealId(setmealId));
            //批量保存套餐和菜品的关联关系
            setmealDishMapper.insertBatch(setmealDishes);
        }
        return row1 > 0;
    }

    @Override
    public PageResult pageQuery(SetmealPageQueryDTO setmealPageQueryDTO) {
        //开启分页
        PageHelper.startPage(setmealPageQueryDTO.getPage(), setmealPageQueryDTO.getPageSize());
        //查询分页数据
        List<SetmealVO> setmealVOS = setmealMapper.selectByPage(setmealPageQueryDTO);
        //向下转型
        Page<SetmealVO> p = (Page<SetmealVO>) setmealVOS;
        //返回结果
        return new PageResult(p.getTotal(), p.getResult());
    }

    @Override
    public boolean deleteByIds(List<Long> ids) {
        /**
         * 1. 判断当前菜品是否在起售中, 如果起售中则不能删除
         * 2. 删除菜品
         */
        int row1 = setmealMapper.selectCountByIdsAndStatus(ids, StatusConstant.ENABLE);
        if (row1 > 0) {
            throw new DeletionNotAllowedException("套餐正在售卖中，不能删除");
        }
        int row2 = setmealMapper.deleteByIds(ids);
        return row2 > 0;
    }

    @Override
    public SetmealVO findById(Long id) {
        return setmealMapper.selectById(id);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateWithDish(SetmealDTO setmealDTO) {
        /**
         * 1. 修改套餐数据
         * 2. 删除套餐和菜品的关联关系
         * 3. 批量插入套餐和菜品的关联关系
         */
        Setmeal setmeal = new Setmeal();
        BeanUtils.copyProperties(setmealDTO, setmeal);
        int row1 = setmealMapper.update(setmeal);
        //删除套餐和菜品的关联关系
        Long setmealId = setmeal.getId();
        //先根据setmealId查询有没有关联关系
        List<SetmealDish> oldSetmealDishes = setmealDishMapper.selectBySetmealId(setmealId);
        if (!CollectionUtils.isEmpty(oldSetmealDishes)) {//存在关联关系, 则删除
            setmealDishMapper.deleteBySetmealId(setmealId);
        }
        //批量插入套餐和菜品的关联关系
        List<SetmealDish> newSetmealDishes = setmealDTO.getSetmealDishes();
        if (!CollectionUtils.isEmpty(newSetmealDishes)) {
            newSetmealDishes.forEach(setmealDish -> setmealDish.setSetmealId(setmealId));
            setmealDishMapper.insertBatch(newSetmealDishes);
        }
        return row1 > 0;
    }

    @Override
    public boolean startOrStop(Integer status, Long id) {
        /**
         * 1. 检查套餐中的菜品是否是启售状态,如果菜品不是启售状态,则不能启售,并且抛出异常信息
         * 2. 改变套餐的起售状态
         */
        if (status == StatusConstant.ENABLE) {//套餐是启售状态,检查菜品状态
            List<Dish> dishList = dishMapper.selectDishBySetmealId(id);
            if (!CollectionUtils.isEmpty(dishList)) {
                dishList.forEach(dish -> {
                    if (dish.getStatus() != StatusConstant.ENABLE) {
                        throw new SetmealEnableFailedException("当前套餐关联的菜品有处于停售状态,不能启售");
                    }
                });
            }
        }
        Setmeal setmeal = Setmeal.builder()
                .id(id)
                .status(status)
                .build();
        int row = setmealMapper.updateStatus(setmeal);
        return row > 0;
    }
}
